<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<title>SCROLLBAR</title>

<link rel="stylesheet" type="text/css" href="../../style.css">
<style type="text/css">
.style1 {
	font-size: large;
}
.style2 {
	color: #FF0000;
}
.style3 {
	color: #008000;
}
</style>
</head>
<body>

<h2>SCROLLBAR<span class="style1"> (creation only) </span> </h2>
<p>Associates a horizontal and/or vertical scrollbar to the element.</p>
<h3>Value</h3>
<p>&quot;VERTICAL&quot;, &quot;HORIZONTAL&quot;, &quot;YES&quot; (both) or
  &quot;NO&quot; (none).</p>
<p>Default: &quot;NO&quot;</p>
<h3>Configuration Attributes (<font size="3">non inheritable</font>)</h3>
<p><a href="../attrib/iup_dx.html">DX</a>:
  Size of the thumb in the horizontal 
  scrollbar. Also the horizontal page size. Default: "0.1".</p>
<p><a href="../attrib/iup_dy.html">DY</a>:
  Size of the thumb in the vertical scrollbar. Also the vertical page size. Default: "0.1".</p>
<p><a href="../attrib/iup_posx.html">POSX</a>:
  Position of the thumb in the horizontal 
  scrollbar. Default: "0.0".</p>
<p><a href="../attrib/iup_posy.html">POSY</a>:
  Position of the thumb in the vertical 
  scrollbar. Default: "0.0".</p>
<p><a href="../attrib/iup_xmin.html">XMIN</a>:
  Minimum value of the horizontal scrollbar. Default: "0.0".</p>
<p><a href="../attrib/iup_xmax.html">XMAX</a>:
  Maximum value of the horizontal scrollbar. Default: "1.0".</p>
<p><a href="../attrib/iup_ymin.html">YMIN</a>:
  Minimum value of the vertical scrollbar. Default: "0.0".</p>
<p><a href="../attrib/iup_ymax.html">YMAX</a>:
  Maximum value of the vertical scrollbar. Default: "1.0".</p>
<p><b>LINEX</b>: The amount the thumb moves when an horizontal step is performed. 
  Default: 1/10th of DX. (since 3.0)</p>
<p><b>LINEY</b>: The amount the thumb moves when a vertical step is performed. 
  Default: 1/10th of DY. (since 3.0)</p>
<p><b><a name="XAUTOHIDE">XAUTOHIDE</a></b>: When enabled, if DX &gt;= XMAX-XMIN then 
  the horizontal scrollbar is hidden. Default: "YES". (since 3.0)</p>
<p><b><a name="YAUTOHIDE">YAUTOHIDE</a></b>: When enabled, if DY &gt;= YMAX-YMIN then 
  the vertical scrollbar is hidden. Default: "YES". (since 3.0)</p>
<p><strong>XHIDDEN</strong> [read-only]: returns if the scrollbar is hidden or not when 
XAUTOHIDE=Yes. (since 3.13)</p>
<p><strong>YHIDDEN</strong> [read-only]: returns if the scrollbar is hidden or not when 
YAUTOHIDE=Yes. (since 3.13)</p>
<p><strong>SB_RESIZE</strong> [read-only]: returns if a scrollbar visibility was 
changed forcing a canvas resize after setting DX or DY. (since 3.26)</p>

<h3>Notes</h3>
<p>The 
  scrollbar allows you to create a virtual space associated to the element. In 
  the image below, such space is marked in <span class="style2"><strong>red</strong></span>, 
  as well as the attributes that affect the composition of this space. In 
<span class="style3"><strong>green</strong></span> you can see how these attributes are 
  reflected on the scrollbar.</p>
<p align="center">
<img src="images/scrollbar.gif" alt="images/scrollbar.gif (2113 bytes)" border="2" hspace="2" vspace="2"></p>
<p>Hence you can clearly deduce that POSX is limited to XMIN and
  XMAX-DX, or&nbsp; <strong>XMIN&lt;=POSX&lt;=XMAX-DX</strong>. </p>
<p>Usually applications configure XMIN and XMAX to a region in World 
coordinates, and set DX to the canvas visible area in World coordinates. Since 
the canvas can have scrollbars and borders, its visible area in pixel 
coordinates can be easily obtained using the <strong>DRAWSIZE</strong> 
attribute.</p>
<p>
<span class="style2"><strong>IMPORTANT:</strong></span> the LINEX, XMAX and XMIN 
attributes are only updated in the scrollbar when the 
DX attribute is updated.</p>
<p>
<span class="style2"><strong>IMPORTANT:</strong></span> when working with a 
virtual space with integer coordinates, set XMAX to the integer size of the 
virtual space, NOT to &quot;width-1&quot;, or the last pixel of the virtual space will 
never be visible. If you decide to let XMAX with the default value of 1.0 
and to control only DX, then use the formula DX=visible_width/width.</p>
<p>
<span class="style2"><strong>IMPORTANT:</strong></span> 
When the virtual space has the same size as the canvas, i.e. when <strong>DX &gt;= XMAX-XMIN</strong>, the 
scrollbar is automatically hidden if <strong>XAUTOHIDE</strong>=Yes. The width 
of the vertical scrollbar (the same as the height of the horizontal scrollbar) 
can be obtained using the SCROLLBARSIZE global attribute (since 3.9).</p>
<p>
The same is valid for YMIN, YMAX, DY and POSY. But remember that the Y axis is 
oriented from top to bottom in IUP. So if you want to consider YMIN and YMAX as 
bottom-up oriented, then the actual YPOS must be obtained using <strong>
YMAX-DY-POSY</strong>.</p>
<p>
<span class="style2"><strong>IMPORTANT:</strong></span> 
Changes in the scrollbar parameters do NOT generate ACTION nor SCROLL_CB 
callback events. If you need to update the canvas contents call your own action 
callback or call <b>IupUpdate</b>. But a change in the DX attribute may generate 
a RESIZE_CB callback event if XAUTOHIDE=Yes.</p>
<p>
If you have to change the properties of the scrollbar (XMIN, XMAX and DX) but 
you want to keep the thumb still (if possible) in the same relative position, 
then you have to also recalculate its position (POSX) using the old position as 
reference to the new one. For example, you can convert it to a 0-1 interval and 
then scale to the new limits:</p>
<pre>old_posx_relative = (old_posx - old_xmin)/(old_xmax - old_xmin)
posx = (xmax - xmin)*old_posx_relative + xmin</pre>
<p>
<strong>IupList,</strong> <strong>IupTree</strong>, and <strong>IupText/IupMultiline</strong> scrollbars are 
automatically managed and do NOT have the POS*, *MIN, *MAX and D* attributes.</p>
<p>
When updating the virtual space size, or when the canvas is resized, if <strong>XAUTOHIDE</strong>=Yes 
then calculating the actual DX size can be very tricky. Here is a a helpful 
algorithm:</p>
<pre>void scrollbar_update(Ihandle* ih, int view_width, int view_height)  /* view_width and view_height is the virtual space size */
{
  int elem_width, elem_height;
  int canvas_width, canvas_height;
  int sb_size = IupGetInt(NULL, "SCROLLBARSIZE");
  int border = IupGetInt(ih, "BORDER");

  IupGetIntInt(ih, "RASTERSIZE", &elem_width, &elem_height);

  /* remove BORDER (always size=1) */
  /* this is available drawing size not considering the scrollbars*/
  elem_width -= 2 * border;  
  elem_height -= 2&nbsp;* border;
  canvas_width = elem_width;
  canvas_height = elem_height;

  /* if view is greater than canvas in one direction,
     then it has scrollbars,
     but this affects the opposite direction */

  if (view_width > elem_width)  /* check for horizontal scrollbar */
    canvas_height -= sb_size;   /* affect vertical size */
  if (view_height > elem_height)
    canvas_width -= sb_size;

  if (view_width <= elem_width && view_width > canvas_width)  /* check again for horizontal scrollbar */
    canvas_height -= sb_size;
  if (view_height <= elem_height && view_height > canvas_height)  /* notice that these two ifs are mutually exclusive */
    canvas_width -= sb_size;

  if (canvas_width < 0) canvas_width = 0;
  if (canvas_height < 0) canvas_height = 0;

  IupSetFloat(ih, &quot;DX&quot;, (float)canvas_width / (float)view_width);  /* normalize to 0-1 assuming XMIN-XMAX=0-1 */
  IupSetFloat(ih, &quot;DY&quot;, (float)canvas_height / (float)view_height);

  /* Another approach is to set DX,DY to canvas_width,canvas_height  
     and XMAX,YMAX to view_width,view_height */
}
</pre>
<p>Inside the canvas ACTION callback, the (x,y) offset for drawing is calculated 
as:</p>
<pre> int x, y, canvas_width, canvas_height;
float posy = IupGetFloat(ih, &quot;POSY&quot;);
float posx = IupGetFloat(ih, &quot;POSX&quot;);

IupGetIntInt(ih, &quot;DRAWSIZE&quot;, &amp;canvas_width, &amp;canvas_height);

if (canvas_width &lt; view_width)
  x = (int)floor(-posx*view_width);
else
  x = (canvas_width - view_width) / 2;  /* no scrollbar, for example, center the view */

if (canvas_height &lt; view_height)
{
  /* posy is top-bottom, CD and OpenGL are bottom-top.
     invert posy reference (YMAX-DY - POSY) */
  float dy = IupGetFloat(ih, &quot;DY&quot;);
  posy = 1.0f - dy - posy;
  y = (int)floor(-posy*view_height);
}
else
  y = (canvas_height - view_height) / 2;  /* no scrollbar, for example, center the view */</pre>
<p>Call <strong>scrollbar_update</strong> from the RESIZE_CB callback and when 
you change the zoom factor that affects <strong>view_width</strong> or <strong>
view_height</strong>.</p>
<h3>Affects</h3>
<p><a href="../elem/iuplist.html">IupList</a>,
<a href="../elem/iupmultiline.html">IupMultiline</a>, <a href="../elem/iupcanvas.html">IupCanvas</a></p>
<h3>See Also</h3>
<p><a href="iup_posx.html">POSX</a>,
<a href="iup_xmin.html">XMIN</a>, <a href="iup_xmax.html">XMAX</a>,
<a href="iup_dx.html">DX</a>, <a href="iup_posy.html">POSY</a>,
<a href="iup_ymin.html">YMIN</a>, <a href="iup_ymax.html">YMAX</a>,
<a href="iup_dy.html">DY</a></p>

</body>

</html>